import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.*;

public class NetworkConnectionThread implements Runnable {
	Thread thisThread = Thread.currentThread();
	
	private String hostName;
	private String hostAddress; 
	private Socket socket;
	private DataInputStream inputFromClient;
	private DataOutputStream outputToClient;
	
	private NetworkCommand lastCommandSent;
	private int timeout;
	
	public void stop ()
	{
		thisThread = null;
	}
	
	public void run ()
	{
		try 
		{
		    while (true) 
		    {
		          String input = inputFromClient.readUTF();

		          NetworkCommand command = null;
		          
		          String[] inputElements = input.split("|");
		          
		          // set NetworkCommand from first in pipe-delimited sequence
		          for(NetworkCommand i : NetworkCommand.values())
		          {
		        	  if(inputElements[0] == i.value()) { command = i; }
		          }
		          
		          switch(command)
		          {
		          	case STAYALIVE:
		          		// respond with AWK, set timeout to 30 seconds
		          		send(NetworkCommand.AWK);
		          		timeout = 30;
		          		break; 
		          		
		          	case TERMINATE:  
		          		// respond with AWK, 
		          		//	if CLIENT then set set game state to OFFLINE, kill thread, 
		          		//	if SERVER then remove player from game, create new computer player, kill thread
		          		send(NetworkCommand.AWK);
		          		closeConnections();
		          		if(Game.getNetworkState() == NetworkState.CLIENT)
		          			Game.stopClient();		          			
		          		else 
		          			Game.stopServer();
		          		
		          		thisThread = null;
		          		break;
		          	
		          	case GAMESTATE: 
		          		// if CLIENT, Game.deserializeState()
		          		//		if SERVER, Game.serializeState()
		          		if(Game.getNetworkState() == NetworkState.CLIENT)
		          			Game.deserializeGameState(inputElements[1]);
		          		else 
		          			send(NetworkCommand.GAMESTATE,Game.serializeGameState());
		          		break; 
		          		
		          	case MAKEMOVE: 
		          		// if SERVER, check if player is current active, 
		          		// record move, 
		          		// check for game state change
		          		// update clients
		          		break; 
		          		
		          	case JOINGAME: 
		          		// if room in game, 
		          		// remove first computer player, 
		          		// add new Player in slot		          		
		          		break;
		          		
		          	case REJECTED: 
		          		// if lastCommandSent == joingame, relay info to user
		          		// if lastCommandSent == makemove, relay "not your turn"
		          		// else throw error
		          		break;
		          		
		          	case AWK: 
		          		// if lastCommandSent == STAYALIVE, lastCommandSent = null, timeout = 30 seconds;
		          		// if lastCommandSent == TERMINATE, if CLIENT then set game state to DISCONNECTED, kill thread, 
		          		//		if SERVER then remove player from game, create new computer player, kill thread
		          		// if lastCommandSent == GAMESTATE, Game.setStateFromSerialized(), lastCommandSent == null
		          		// if lastCommandSent == MAKEMOVE, lastCommandSent == null
		          		break;
		          		
		          	default:
		          }
		    }
		}
		catch(IOException e) 
		{
			System.err.println(e);
		}
	}
	
	public void send (NetworkCommand command, String commandText) throws IOException
	{		
		lastCommandSent = command;
		outputToClient.writeUTF((command.value()+"|"+commandText));
	}
	public void send (NetworkCommand command) throws IOException
	{		
		lastCommandSent = command;
		outputToClient.writeUTF((command.value()));
	}
	
	private void closeConnections() throws IOException
	{
		this.inputFromClient.close();
		this.outputToClient.close();
	}
	
	public NetworkConnectionThread (Socket socket) throws IOException
	{
		this.socket = socket;
		InetAddress inetAddress = socket.getInetAddress();
		this.hostName = inetAddress.getHostName();
		this.hostAddress = inetAddress.getHostAddress();
		
		this.inputFromClient = new DataInputStream(socket.getInputStream());
		this.outputToClient = new DataOutputStream(socket.getOutputStream());
		
		this.lastCommandSent = null;
		this.timeout = 30;
	}

}